package 压缩流;
import java.io.*;
import java.util.zip.*;
// 压缩目录
public class ZipDirectoryExample {
    public static void main(String[] args) {
        String sourceDir = "docs";
        String zipFile = "docs.zip";

        try (FileOutputStream fos = new FileOutputStream(zipFile);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            zipDirectory(sourceDir, sourceDir, zos);
            System.out.println("目录压缩完成: " + zipFile);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将指定目录压缩到ZIP输出流中
     *
     * @param rootDir 根目录路径，用于计算相对路径
     * @param sourceDir 要压缩的源目录路径
     * @param zos ZIP输出流，用于写入压缩数据
     * @throws IOException 当IO操作出现异常时抛出
     */
    private static void zipDirectory(String rootDir, String sourceDir, ZipOutputStream zos) throws IOException {
        File dir = new File(sourceDir);

        File[] files = dir.listFiles();

        if (files == null) return;

        for (File file : files) {
            if (file.isDirectory()) {
                // 递归处理子目录
                zipDirectory(rootDir, file.getAbsolutePath(), zos);
                continue;
            }

            try (FileInputStream fis = new FileInputStream(file)) {
                // 创建相对路径的ZIP条目

                // 获取根目录的绝对路径
                String rootDirPath = new File(rootDir).getAbsolutePath();

                // 获取当前文件的绝对路径
                String fileAbsolutePath = file.getAbsolutePath();

                // 计算需要截取的起始位置（跳过根目录路径和路径分隔符）
                int startIndex = rootDirPath.length() + 1;

                // 从文件绝对路径中提取相对路径部分
                String zipPath = fileAbsolutePath.substring(startIndex);


                ZipEntry zipEntry = new ZipEntry(zipPath);
                zos.putNextEntry(zipEntry);

                // 写入文件内容
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) >= 0) {
                    zos.write(buffer, 0, length);
                }

                zos.closeEntry();
            }
        }
    }
}